package com.agileplex.codeminer.scm.svn;

import com.agileplex.codeminer.commons.MapContainer;
import com.agileplex.codeminer.scm.IVersion;

/**
 * Subversion Version implements
 * 
 * @creator Weiming Yin
 * @date 2007-6-5
 * 
 * @lastmodified
 * @author $Author: yinweiming $
 * @version $Revision: 14 $, $Date: 2007-06-11 15:37:58 +0000 (Mon, 11 Jun 2007) $
 */

public class SvnVersion implements IVersion<Long> {

	private static MapContainer<SvnRepository, Long, SvnVersion> versionMc = new MapContainer<SvnRepository, Long, SvnVersion>();

	public static SvnVersion NULL = new SvnVersion(null, -1);

	private long v;

	private SvnRepository repository;

	protected SvnVersion(SvnRepository repository, long v) {
		this.repository = repository;
		this.v = v;
	}

	public Long getVersion() {
		return v;
	}

	public SvnVersion getPrevious() {
		if (v == 0) {
			throw new SvnException(SvnCause.NO_PREVIOUS_VERSION);
		}
		
		long n = v - 1;
		SvnVersion version = versionMc.get(repository, n);
		if (version == null) {
			version = new SvnVersion(repository, n);
			versionMc.set(repository, n, version);
		}
		
		return version;
	}
	
	public String toString() {
		return "r" + this.v;
	}
	
	public boolean equals(Object o) {
		if (o == this) {
			return true;
		}
		
		if (!(o instanceof SvnVersion)) {
			return false;
		}
		
		SvnVersion a = (SvnVersion) o;
		return a.getVersion() == this.v && a.repository.equals(this.repository);
	}
	
	@Override
	public int hashCode() {
		final int PRIME = 31;
		int result = 1;
		result = PRIME * result + ((repository == null) ? 0 : repository.hashCode());
		result = PRIME * result + (int) (v ^ (v >>> 32));
		return result;
	}	
    
    public static SvnVersion getSvnVersion(SvnRepository repository, long v) {
        SvnVersion version = versionMc.get(repository, v);
        if (version == null) {
            version = new SvnVersion(repository, v);
            versionMc.set(repository, v, version);
        }
        
        return version;
    }
}
